package com.xpq.petserver.controller;

import com.xpq.petserver.entity.R;
import com.xpq.petserver.entity.dto.*;
import com.xpq.petserver.entity.request.user.UpdatePasswordRequest;
import com.xpq.petserver.entity.request.user.UpdatePhoneRequest;
import com.xpq.petserver.entity.request.user.UserBasicInfoRequest;
import com.xpq.petserver.exception.AppException;
import com.xpq.petserver.exception.AppExceptionCodeMsg;
import com.xpq.petserver.util.CheckUtil;
import com.xpq.petserver.converter.UserConverter;
import com.xpq.petserver.entity.request.user.LoginRegisterRequest;
import com.xpq.petserver.service.UserService;
import com.xpq.petserver.util.JwtUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 用户表相关接口
 * @author XPQ
 * @date 2022-04-22
 */
@Slf4j
@Tag(name = "用户模块")
@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    /**
     * 用户注册接口
     * @param loginRegisterRequest 用户注册信息
     * @return
     */
    @Operation(summary = "用户注册接口")
    @Parameter(name = "loginRegisterRequest", description = "用户注册信息")
    @PostMapping("/register")
    public R register(@RequestBody LoginRegisterRequest loginRegisterRequest){
        // 校验手机号码
        if(!CheckUtil.checkPhoneNum(loginRegisterRequest.getPhone())) {
            throw new AppException(AppExceptionCodeMsg.PHONE_NUMBER_FORMAT_ERROR);
        }
        // 校验密码
        if(!checkPassword(loginRegisterRequest.getPassword())) {
            throw new AppException(AppExceptionCodeMsg.EMPTY_PASSWORD);
        }
        // 手机号和密码正确后
        RegisterUserDTO registerUserDTO = UserConverter.INSTANCE.toRegisterUserDTO(loginRegisterRequest);
        return userService.registerUser(registerUserDTO);
    }

    /**
     * 校验密码是否合法
     * @param password
     * @return
     */
    private boolean checkPassword(String password) {
        // 密码不能为空，如null、""、password==md5("").
        boolean isPasswordNotNull = password != null
                && "".equals(password)
                && password.equals(DigestUtils.md5DigestAsHex("".getBytes()));
        if(!isPasswordNotNull) { // 密码为空
            return false;
        }
        return true;
    }

    /**
     * 用户登录接口
     * @param loginRegisterRequest 用户登录信息
     * @return
     */
    @Operation(summary = "用户登录接口")
    @Parameter(name = "loginRegisterRequest", description = "用户登录信息")
    @PostMapping("/login")
    public R login(@RequestBody LoginRegisterRequest loginRegisterRequest) {
        log.debug("前端传过来的参数：{}", loginRegisterRequest);
        LoginDTO loginDTO = UserConverter.INSTANCE.toLoginDTO(loginRegisterRequest);
        log.debug("转换后的参数：{}", loginDTO);
        return userService.login(loginDTO);
    }

    /**
     * 判断用户是否一已登录，用于前端路由守卫鉴权用
     * @return
     */
    @Operation(summary = "用户是否已登录判断接口")
    @PostMapping("/isLogin")
    public R isLogin() {
        return R.success(null);
    }

    /**
     * 获取用户信息
     * @param request 获取用户token
     * @return 返回用户头像
     */
    @Operation(summary = "获取用户信息接口")
    @PostMapping("/getUserInfo")
    public R getUserInfo(HttpServletRequest request) {
        String token = request.getHeader("token");
        return userService.getUserInfo(JwtUtil.getId(token));
    }

    /**
     * 头像上传接口
     * @param avatar 头像文件
     * @param httpServletRequest 获取token用
     * @return 用户新的头像地址
     * @throws IOException
     */
    @Operation(summary = "头像上传接口")
    @Parameter(name = "avatar", description = "头像文件")
    @PostMapping("/uploadAvatar")
    public R uploadAvatar(@RequestPart("avatarFile") MultipartFile avatar, HttpServletRequest httpServletRequest){
        if (avatar == null) { // 头像不能为空
            throw new AppException(AppExceptionCodeMsg.EMPTY_AVATAR);
        }
        String token = httpServletRequest.getHeader("token");
        return userService.uploadAvatar(avatar, JwtUtil.getId(token));
    }

    /**
     * 修改用户基本信息
     * @param userBasicInfo 用户基本信息
     * @param request       获取token来获取用户id
     * @return
     */
    @Operation(summary = "修改用户基本信息接口")
    @Parameter(name = "userBasicInfo", description = "用户基本信息")
    @PostMapping("/updateUserBasicInfo")
    public R updateUserBasicInfo(@RequestBody UserBasicInfoRequest userBasicInfo, HttpServletRequest request) {
        UserBasicInfoDTO userBasicInfoDTO = UserConverter.INSTANCE.toUserBasicInfoDTO(userBasicInfo);
        String token = request.getHeader("token");
        userBasicInfoDTO.setId(JwtUtil.getId(token));
        return userService.updateUserBasicInfo(userBasicInfoDTO);
    }

    /**
     * 修改用户密码接口
     * @param updatePasswordRequest
     * @param request
     * @return
     */
    @Operation(summary = "修改用户密码接口")
    @Parameter(name = "updatePasswordRequest", description = "原新密码")
    @PostMapping("/updatePassword")
    public R updatePassword(@RequestBody UpdatePasswordRequest updatePasswordRequest, HttpServletRequest request) {
        // 校验密码
        if(!checkPassword(updatePasswordRequest.getNewPassword())) {
            throw new AppException(AppExceptionCodeMsg.EMPTY_PASSWORD);
        }
        UpdatePasswordDTO updatePasswordDTO = UserConverter.INSTANCE.toUpdatePasswordDTO(updatePasswordRequest);
        String token = request.getHeader("token");
        updatePasswordDTO.setId(JwtUtil.getId(token));
        return userService.updatePassword(updatePasswordDTO);
    }

    @Operation(summary = "修改用户手机号接口")
    @Parameter(name = "updatePhoneRequest", description = "新手机号和密码")
    @PostMapping("/updatePhone")
    public R updatePhone(@RequestBody UpdatePhoneRequest updatePhoneRequest, HttpServletRequest request) {
        // 校验手机号码
        if(!CheckUtil.checkPhoneNum(updatePhoneRequest.getNewPhone())) {
            throw new AppException(AppExceptionCodeMsg.PHONE_NUMBER_FORMAT_ERROR);
        }
        UpdatePhoneDTO updatePhoneDTO = UserConverter.INSTANCE.toUpdatePhoneDTO(updatePhoneRequest);
        String token = request.getHeader("token");
        updatePhoneDTO.setId(JwtUtil.getId(token));
        return userService.updatePhone(updatePhoneDTO);
    }
}
